#include "xmppcore/presence.h"
#include "xmppcore/xmlwriter.h"
#include "xmppcore/constants.h"

namespace yoohoo_xmppcore {

const ProtocolKey Presence::PROTOCOL_KEY = ProtocolKey(XMPP_STRING_PRESENCE);
const int Presence::PRIORITY_NOT_SET = -1;

Presence::Presence() {
	_pd = new PresenceSharedData;
}

Presence::Presence(const Presence& other) : Stanza(other), _pd(other._pd) {
}

void Presence::setPresenceShow(Presence::PresenceShow presenceShow) {
	_pd->presenceShow = presenceShow;
}

Presence::PresenceShow Presence::presenceShow() const {
	return _pd->presenceShow;
}

void Presence::setStatus(QList<XmlLangText> status) {
	_pd->status = status;
}

QList<XmlLangText>& Presence::status() {
	return _pd->status;
}

void Presence::setPriority(int priority) {
	_pd->priority = priority;
}

int Presence::priority() const {
	return _pd->priority;
}

Stanza::StanzaKind Presence::stanzaKind() const {
	return Stanza::StanzaKindPresence;
}

void Presence::setPresenceType(Presence::PresenceType presenceType) {
	_pd->presenceType = presenceType;
	if (Presence::PresenceTypeAvailable == _pd->presenceType) {
		_d->type = "available";
	} else if (Presence::PresenceTypeUnavailable == _pd->presenceType) {
		_d->type = "unavailable";
	} else if (Presence::PresenceTypeSubscribe == _pd->presenceType) {
		_d->type = "subscribe";
	} else if (Presence::PresenceTypeUnsubscribe == _pd->presenceType) {
		_d->type = "unsubscribe";
	} else if (Presence::PresenceTypeSubscribed == _pd->presenceType) {
		_d->type = "subscribed";
	} else if (Presence::PresenceTypeUnsubscribed == _pd->presenceType){
		_d->type = "unsubscribed";
	} else {
		_d->type.clear();
	}
}

Presence::PresenceType Presence::presenceType() const {
	return _pd->presenceType;
}

void Presence::doToXml(XmlWriter* xmlWriter) {
	if (Presence::PresenceShowNone != _pd->presenceShow) {
		xmlWriter->writeStartElement("show");
		if (Presence::PresenceShowAway == _pd->presenceShow) {
			xmlWriter->writeCharacters("away", false);
		} else if (Presence::PresenceShowChat == _pd->presenceShow) {
			xmlWriter->writeCharacters("chat", false);
		} else if (Presence::PresenceShowDND == _pd->presenceShow) {
			xmlWriter->writeCharacters("dnd", false);
		} else if (Presence::PresenceShowNone == _pd->presenceShow) {
			xmlWriter->writeCharacters("xa", false);
		}
		xmlWriter->writeEndElement();
	}

	if (!_pd->status.isEmpty()) {
		foreach (XmlLangText aStatus, _pd->status) {
			xmlWriter->writeStartElement("status");
			if (!aStatus.xmlLang().isEmpty()) {
				xmlWriter->writeAttribute("xml:lang", aStatus.xmlLang());
			}
			xmlWriter->writeCharacters(aStatus.text());
			xmlWriter->writeEndElement();
		}
	}

	if (_pd->priority != PRIORITY_NOT_SET) {
		xmlWriter->writeStartElement("priority");
		xmlWriter->writeCharacters(QString("%d").arg(_pd->priority));
		xmlWriter->writeEndElement();
	}
}

PresenceSharedData::PresenceSharedData() : priority(Presence::PRIORITY_NOT_SET), presenceShow(Presence::PresenceShowNone) {
}

PresenceSharedData::PresenceSharedData(const PresenceSharedData& other) : QSharedData(other), presenceShow(other.presenceShow),
	status(other.status), priority(other.priority), presenceType(other.presenceType) {
}

}
